/*
 *  Copyright (c)  2016-NOW  Jacars Co.Ltd.
 *  All rights reserved.
 */
package com.jacars.biz.user.service.impl;

import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jacars.biz.user.dao.mapper.*;
import com.jacars.biz.user.dao.model.*;
import com.jacars.biz.user.dao.service.JsptMenuService;
import com.jacars.biz.user.dao.service.JsptRoleMenuService;
import com.jacars.biz.user.dao.service.JsptTenantService;
import com.jacars.biz.user.service.TenantService;
import com.jacars.common.constant.CommonConstant;
import com.jacars.common.model.JsptMenu;
import com.jacars.common.model.JsptRole;
import com.jacars.common.model.JsptUser;
import com.jacars.common.tenant.TenantId;
import com.jacars.common.utils.FuncUtil;
import com.jacars.common.utils.ids.IdGenerator;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author Chill
 */
@Service
public class TenantServiceImpl implements TenantService {

    private final JsptTenantService jsptTenantService;
    private final TenantId tenantId;
    private final JsptRoleMapper jsptRoleMapper;
    private final JsptMenuService jsptMenuService;
    private final JsptDeptMapper jsptDeptMapper;
    private final JsptPostMapper jsptPostMapper;
    private final JsptUserMapper jsptUserMapper;
    private final JsptUserRoleMapper jsptUserRoleMapper;
    private final JsptRoleMenuService jsptRoleMenuService;
    private final JsptClientMapper JsptClientMapper;
    private final PasswordEncoder passwordEncoder;

    public TenantServiceImpl(JsptTenantService jsptTenantService, TenantId tenantId, JsptRoleMapper jsptRoleMapper, JsptMenuService jsptMenuService, JsptDeptMapper jsptDeptMapper, JsptPostMapper jsptPostMapper, JsptUserMapper jsptUserMapper, JsptUserRoleMapper jsptUserRoleMapper, JsptRoleMenuService jsptRoleMenuService, com.jacars.biz.user.dao.mapper.JsptClientMapper jsptClientMapper, PasswordEncoder passwordEncoder) {
        this.jsptTenantService = jsptTenantService;
        this.tenantId = tenantId;
        this.jsptRoleMapper = jsptRoleMapper;
        this.jsptMenuService = jsptMenuService;
        this.jsptDeptMapper = jsptDeptMapper;
        this.jsptPostMapper = jsptPostMapper;
        this.jsptUserMapper = jsptUserMapper;
        this.jsptUserRoleMapper = jsptUserRoleMapper;
        this.jsptRoleMenuService = jsptRoleMenuService;
        this.JsptClientMapper = jsptClientMapper;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public JsptTenant getByTenantId(String tenantId) {
        return jsptTenantService.getOne(Wrappers.<JsptTenant>query().lambda().eq(JsptTenant::getTenantId, tenantId));
    }

    @Override
    @InterceptorIgnore(tenantLine = "true")
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTenant(JsptTenant tenant) {
        if (FuncUtil.isEmpty(tenant.getId())) {
            List<JsptTenant> tenants = jsptTenantService.list();
            List<String> codes = tenants.stream().map(JsptTenant::getTenantId).collect(Collectors.toList());
            String tenantId = getTenantId(codes);
            tenant.setTenantId(tenantId);
            // 新建租户对应的默认角色
            JsptRole role = new JsptRole();
            role.setId(IdGenerator.getId());
            role.setTenantId(tenantId);
            role.setParentId(0L);
            role.setRoleName(tenant.getTenantName() + "管理员");
            role.setRoleAlias("admin1");
            role.setSort(2);
            role.setIsDeleted(0);
            role.setCreateTime(new Date());
            role.setUpdateTime(new Date());
            jsptRoleMapper.saveTenantRole(role);

            // 为角色分配菜单。分配所有菜单的权限
            List<JsptMenu> all = jsptMenuService.findAll();
            List<JsptRoleMenu> roleMenuList = new ArrayList<>();
            roleMenuList.addAll(all.stream().map(k -> {
                JsptRoleMenu jsptRoleMenu = new JsptRoleMenu();
                jsptRoleMenu.setRoleId(role.getId());
                jsptRoleMenu.setMenuId(k.getId());
                return jsptRoleMenu;
            }).collect(Collectors.toList()));
            jsptRoleMenuService.saveBatch(roleMenuList);

            // 新建租户对应的默认部门
            JsptDept jsptDept = new JsptDept();
            jsptDept.setId(IdGenerator.getId());
            jsptDept.setTenantId(tenantId);
            jsptDept.setParentId(0L);
            jsptDept.setDeptName(tenant.getTenantName());
            jsptDept.setFullName(tenant.getTenantName());
            jsptDept.setSort(2);
            jsptDept.setIsDeleted(0);
            jsptDept.setCreateTime(new Date());
            jsptDept.setUpdateTime(new Date());
            jsptDeptMapper.saveTenantDept(jsptDept);
            // 新建租户对应的默认岗位
            JsptPost post = new JsptPost();
            post.setId(IdGenerator.getId());
            post.setTenantId(tenantId);
            post.setCategory(1);
            post.setPostCode("ceo");
            post.setPostName("首席执行官");
            post.setRemark("首席执行官");
            post.setStatus(1);
            post.setIsDeleted(0);
            post.setSort(1);
            jsptPostMapper.saveTenantPost(post);
            // 新建租户对应的默认管理用户
            JsptUser user = new JsptUser();
            user.setId(IdGenerator.getId());
            user.setTenantId(tenantId);
            user.setUsername("admin");
            user.setRealName("admin");
            user.setNickName("admin");
            user.setSort(13);

            //初始化密码为123456
            user.setPassword(passwordEncoder.encode(CommonConstant.DEF_USER_PASSWORD));
            user.setDeptId(jsptDept.getId());
            user.setPostId(FuncUtil.toStr(post.getId()));
            user.setSex(CommonConstant.GENDER_MALE);
            user.setStatus(CommonConstant.USER_ENABLE);
            user.setIsDeleted(CommonConstant.DB_NOT_DELETED);
            jsptUserMapper.saveTenantUser(user);
            // 新建人员角色关系
            JsptRoleUser jsptRoleUser = new JsptRoleUser();
            jsptRoleUser.setRoleId(role.getId());
            jsptRoleUser.setUserId(user.getId());
            jsptUserRoleMapper.saveTenantUserRole(jsptRoleUser);

            //新建该租户的client信息
            //当不同租户使用不同前端的时候，才需要创建client
            //if (isUnifiedFront) {
            //    JsptClient jsptClient = new JsptClient();
            //    jsptClient.setId(IdGenerator.getId());
            //    // oAuthClient.setTenantId(tenantId);
            //    jsptClient.setClientName(tenant.getTenantName());
            //    jsptClient.setClientId(tenantId);
            //    jsptClient.setClientSecret(passwordEncoder.encode(CommonConstant.DEF_USER_PASSWORD));
            //    jsptClient.setClientSecretStr(CommonConstant.DEF_USER_PASSWORD);
            //    jsptClient.setScope("all");
            //    jsptClient.setAuthorizedGrantTypes("authorization_code,password,client_credentials,implicit,refresh_token,password_code,openId,mobile_password");
            //    jsptClient.setAccessTokenValiditySeconds(18000);
            //    jsptClient.setRefreshTokenValiditySeconds(28800);
            //    jsptClient.setAdditionalInformation("{}");
            //    jsptClient.setAutoapprove("true");
            //    jsptClient.setCreateTime(new Date());
            //    jsptClient.setUpdateTime(new Date());
            //    JsptClientMapper.saveTenantClient(jsptClient);
            //}

            //保存租户信息
            boolean temp = jsptTenantService.saveOrUpdate(tenant);
            // TenantContextHolder.setTenant(oldTenantId);
            return temp;
        }
        return jsptTenantService.saveOrUpdate(tenant);
    }

    private String getTenantId(List<String> codes) {
        String code = tenantId.generate();
        if (codes.contains(code)) {
            return getTenantId(codes);
        }
        return code;
    }
}
